/*
 * PhotonRTOS础光实时操作系统 -- 测试代码
 *
 * Copyright (C) 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Jiayuan Liang <liangjiayuan@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include "utest.h"

/**
 * =========================================配置任务属性=========================================
 */
DeclareTask(UnitTestTask, AUTOSTART(1), PRIORITY(1), TASK_FLAG(TF_EXTENDED),
	APP_MODE(OSDEFAULTAPPMODE), CORE_ID(0), TASK_TIME_FRAME(0),
	ISR_TIME_FRAME(0), ISR_TIME_BUDGET(10000), TASK_TIME_BUDGET(5000000), APP_ID(0), SchedPolicy(SCHED_FIFO));

DeclareTask(TestTask1, AUTOSTART(0), PRIORITY(2), TASK_FLAG(TF_EXTENDED),
	APP_MODE(OSDEFAULTAPPMODE), CORE_ID(0), TASK_TIME_FRAME(0),
	ISR_TIME_FRAME(0), ISR_TIME_BUDGET(10000), TASK_TIME_BUDGET(1000000), APP_ID(0), SchedPolicy(SCHED_FIFO));
	
DeclareTask(TestTask2, AUTOSTART(0), PRIORITY(3), TASK_FLAG(TF_EXTENDED),
	APP_MODE(OSDEFAULTAPPMODE), CORE_ID(1), TASK_TIME_FRAME(0),
	ISR_TIME_FRAME(0), ISR_TIME_BUDGET(10000), TASK_TIME_BUDGET(1000000), APP_ID(1), SchedPolicy(SCHED_FIFO));

#ifdef CONFIG_IOC
DeclareTask(UnitIocTask, AUTOSTART(1), PRIORITY(1), TASK_FLAG(TF_EXTENDED),
	APP_MODE(OSDEFAULTAPPMODE), CORE_ID(1), TASK_TIME_FRAME(0),
	ISR_TIME_FRAME(0), ISR_TIME_BUDGET(10000), TASK_TIME_BUDGET(5000000), APP_ID(1), SchedPolicy(SCHED_FIFO));
#endif

#ifdef CONFIG_AUTOSAR_MEMORY_PROTECTION
struct app_address_range app_address_range[AUTOSAR_NR_APPLICATION] = {
		{
				data_range : {__app0_data_start, __app0_data_end, READABLE | WRITABLE}
		},
		{
				data_range : {__app1_data_start, __app1_data_end, READABLE | WRITABLE}
		},
};

struct task_address_range task_address_range[OS_NR_TASK] = {
		{
				data_range : {__app0_data_start, __app0_data_end, READABLE | WRITABLE},
				code_range : {__app0_code_start, __app0_code_end, EXECUTABLE},
		},
		{
				data_range : {__app0_data_start, __app0_data_end, READABLE | WRITABLE},
				code_range : {__app0_code_start, __app0_code_end, EXECUTABLE},
		},
		{
				data_range : {__app1_data_start, __app1_data_end, READABLE | WRITABLE},
				code_range : {__app1_code_start, __app1_code_end, EXECUTABLE},
		},
		{
				data_range : {__app1_data_start, __app1_data_end, READABLE | WRITABLE},
				code_range : {__app1_code_start, __app1_code_end, EXECUTABLE},
		},

};
#endif

/**
 * 所有预定义任务列表，这里只定义任务属性
 * 由生成工具产生
 */
struct osek_task_attr *osek_task_attrs[OS_NR_TASK] = {
	[0] = &OS_TASK_ATTR_UnitTestTask,
	[1] = &OS_TASK_ATTR_TestTask1,
	[2] = &OS_TASK_ATTR_TestTask2,
#ifdef CONFIG_IOC
	[3] = &OS_TASK_ATTR_UnitIocTask,
#endif
};


/**
 * =========================================配置alarm属性=========================================
 */
DeclareAlarm(Alarm1, (AUTOSAR_NR_COUNTER - 1), OSDEFAULTAPPMODE);
DeclareAlarm(Alarm2, (AUTOSAR_NR_COUNTER - 1), OSDEFAULTAPPMODE);
DeclareAlarm(Alarm3, (AUTOSAR_NR_COUNTER - 1), OSDEFAULTAPPMODE);


struct osek_alarm_attr *osek_alarm_attrs[OS_NR_ALARM] = {
	[0] = &OS_ALARM_ATTR_Alarm1,
	[1] = &OS_ALARM_ATTR_Alarm2,
	[2] = &OS_ALARM_ATTR_Alarm3,
};

/**
 * =========================================配置os-app属性=========================================
 */
extern void StartupHookApp0(void);
extern void ShutdownHookApp0(void);
extern void ErrorHookApp0(StatusType err);
#if AUTOSAR_NR_APPLICATION > 1
extern void StartupHookApp1(void);
extern void ShutdownHookApp1(void);
extern void ErrorHookApp1(StatusType err);
#endif

#if defined(AUTOSAR_OS_APPLICATION)
struct os_application_attr autosar_os_app_attr[AUTOSAR_NR_APPLICATION] = {
	{StartupHookApp0, ShutdownHookApp0, ErrorHookApp0},
#if AUTOSAR_NR_APPLICATION > 1
	{StartupHookApp1, ShutdownHookApp1, ErrorHookApp1},
#endif
};
#endif /* defined(AUTOSAR_OS_APPLICATION) */

#ifdef CONFIG_IOC

static VAR(uint8, AUTOMATIC) data_buf0[1600];
static VAR(uint8, AUTOMATIC) data_buf1[1600];
static VAR(uint8, AUTOMATIC) data_buf2[1600];
static VAR(uint8, AUTOMATIC) data_buf3[1600];

static FUNC(void, OS_CODE) function_ioc_cb1(void)
{
}

static FUNC(void, OS_CODE) function_ioc_cb2(void)
{
}

OsIocBufferConfigType group_queue[] = { 
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf0),
		OS_IOC_SET_CALLBACK_POINT(function_ioc_cb1)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf0),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf0),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf0),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
};
OsIocBufferConfigType nogroup_queue[]  = {
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf1),
		OS_IOC_SET_CALLBACK_POINT(function_ioc_cb2)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf1),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf1),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf1),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
};
OsIocBufferConfigType nogroup_noqueue[]  = {
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf2),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf2),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf2),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf2),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
};
OsIocBufferConfigType group_noqueue[]  = {
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf3),
		OS_IOC_SET_CALLBACK_POINT(function_ioc_cb2)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf3),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf3),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
	{
		OS_IOC_SET_BUFFER_SIZE(400),
		OS_IOC_SET_BUFFER_POINT(data_buf3),
		OS_IOC_SET_CALLBACK_POINT(NULL_PTR)
	},
};

void config_to_ioc(void)
{
	VAR(uint32, AUTOMATIC) i;
	for (i = 0; i < sizeof(group_queue)/sizeof(group_queue[0]); i++) {
		smp_lock_init(&group_queue[i].RingInfo.lock);
	}
	for (i = 0; i < sizeof(nogroup_queue)/sizeof(nogroup_queue[0]); i++) {
		smp_lock_init(&nogroup_queue[i].RingInfo.lock);
	}
	for (i = 0; i < sizeof(nogroup_noqueue)/sizeof(nogroup_noqueue[0]); i++) {
		smp_lock_init(&nogroup_noqueue[i].RingInfo.lock);
	}
	for (i = 0; i < sizeof(group_noqueue)/sizeof(group_noqueue[0]); i++) {
		smp_lock_init(&group_noqueue[i].RingInfo.lock);
	}
}
#endif
